package com.erp.user.controller;

import com.alibaba.fastjson.JSONObject;
import com.erp.user.domain.ErpDistributionUser;
import com.erp.user.domain.ErpDistributionUserBasicInfo;
import com.erp.user.domain.bo.ErpDistributionUserBo;
import com.erp.user.domain.param.DistributionParam;
import com.erp.user.domain.vo.ErpDistributionUserVo;
import com.erp.user.mapper.ErpDistributionUserBasicInfoMapper;
import com.erp.user.mapper.ErpDistributionUserMapper;
import com.erp.user.service.IErpDistributionUserBasicInfoService;
import com.erp.user.service.IErpDistributionUserService;
import com.ruoyi.common.core.annotation.RepeatSubmit;
import com.ruoyi.common.core.constant.SecurityConstants;
import com.ruoyi.common.core.domain.PageQuery;
import com.ruoyi.common.core.domain.R;
import com.ruoyi.common.core.utils.SpringUtils;
import com.ruoyi.common.core.web.oldController.BaseController;
import com.ruoyi.common.core.web.oldPage.TableDataInfo;
import com.ruoyi.common.log.annotation.Log;
import com.ruoyi.common.log.enums.BusinessType;
import com.ruoyi.system.api.RemoteDeptService;
import com.ruoyi.system.api.RemoteSysConfigService;
import com.ruoyi.system.api.RemoteUserService;
import com.ruoyi.system.api.domain.SysDept;
import com.ruoyi.system.api.domain.SysUser;
import com.ruoyi.system.api.model.LoginUser;
import com.ruoyi.wallet.api.RemoteWalletService;
import lombok.RequiredArgsConstructor;
import org.springframework.amqp.rabbit.core.RabbitTemplate;
import org.springframework.transaction.annotation.Transactional;
import org.springframework.validation.annotation.Validated;
import org.springframework.web.bind.annotation.*;

import javax.annotation.Resource;
import java.math.BigDecimal;
import java.util.*;

/**
 * 代理开户信息
 *
 * @author erp
 * @date 2023-05-08
 */
@Validated
@RequiredArgsConstructor
@RestController
@RequestMapping("/distribution/agent")
public class ErpAgentInfoController extends BaseController {

    private final RemoteUserService remoteUserService;
    private final RemoteWalletService remoteWalletService;
    private final RemoteDeptService remoteDeptService;
    private final RemoteSysConfigService configService;
    @Resource
    RabbitTemplate rabbitTemplate = SpringUtils.getBean(RabbitTemplate.class);
    @Resource
    IErpDistributionUserService distributionUserService;
    @Resource
    ErpDistributionUserMapper distributionUserMapper;
    @Resource
    IErpDistributionUserBasicInfoService distributionUserBasicInfoService;
    @Resource
    ErpDistributionUserBasicInfoMapper distributionUserBasicInfoMapper;


    /**
     * @Description: 查询代理开户信息列表
     * @Author: j.zh
     * @Date: 2024/5/4
     * @param bo
     * @param pageQuery
     * @return
     * @Version: 4.0.0
    **/
    @GetMapping("/list")
    public TableDataInfo<ErpDistributionUserVo> list(ErpDistributionUserBo bo, PageQuery pageQuery) {
        bo.setType(2);
        return distributionUserService.queryPageList(bo, pageQuery);
    }

    /**
     * @Description: 根据分公司id查询旗下的所有代理
     * @Author: j.zh
     * @Date: 2024/5/4
     * @param parentBranchId
     * @return java.util.List<java.lang.Object>
     * @Version: 4.0.0
    **/
    @GetMapping("/getAgentByBranchId")
    public List<Object> getAgentByBranchId(Long parentBranchId) {
        List<ErpDistributionUser> erpAgentInfos = distributionUserService.getListByIdAndType(parentBranchId, 1);
        List<Object> list = new ArrayList<>();
        if (erpAgentInfos != null) {
            erpAgentInfos.forEach(vo -> {
                Map<String, Object> map = new HashMap<>();
                Long id = vo.getDistributionUserId();
                R<Object> objectR = remoteUserService.selectUserById(vo.getUserId());
                String toJSONString = JSONObject.toJSONString(objectR.getData());
                SysUser sysUser = JSONObject.parseObject(toJSONString, SysUser.class);
                String corporateName = sysUser.getUserName() + " "
                        + distributionUserBasicInfoService.getByDistributionUserId(vo.getDistributionUserId()).getLegalPerson() + " "
                        + vo.getIdentityCode();
                map.put("label", corporateName);
                map.put("value", id);
                list.add(map);
            });
        }

        return list;
    }

    /**
     * 导出代理开户信息列表
     */
//    // @SaCheckPermission("system:agentInfo:export")
//    @Log(title = "代理开户信息", businessType = BusinessType.EXPORT)
//    @PostMapping("/export")
//    public void export(ErpAgentInfoBo bo, HttpServletResponse response) {
//        List<ErpAgentInfoVo> list = iErpAgentInfoService.queryList(bo);
////        ExcelUtil.exportExcel(list, "代理开户信息", ErpAgentInfoVo.class, response);
//    }

    /**
     * 获取代理开户信息详细信息
     *
     * @param id 主键
     */
    // @SaCheckPermission("system:agentInfo:query")
//    @GetMapping("/{id}")
//    public R<ErpAgentInfoVo> getInfo(@NotNull(message = "主键不能为空")
//                                     @PathVariable Long id) {
//        return R.ok(iErpAgentInfoService.queryById(id));
//    }

    /**
     * @Description: 新增代理开户信息
     *
     * TODO 合伙人、代理、个人ERP新增后，提成分配还有问题，涉及到钱包表、收入表和流水表，暂时跳过，后改
     *
     * @Author: j.zh
     * @Date: 2024/7/4
     * @param param
     * @return
     * @Version: 4.2.0
    **/
    @Log(title = "代理开户信息", businessType = BusinessType.INSERT)
    @RepeatSubmit()
    @Transactional
    @PostMapping("/add")
    public R<Void> add(@RequestBody DistributionParam param) {
        /** 注册系统用户 **/
        // 获取注册信息
        SysUser user = param.getUser();
        // 创建新部门
        SysDept sysDept = new SysDept();
        // 部门公共信息
        sysDept.setDeptName(param.getDistributionUserBasicInfo().getCorporateName());
        sysDept.setEmail(user.getEmail());
        sysDept.setLeader(param.getDistributionUserBasicInfo().getLegalPerson());
        sysDept.setPhone(user.getPhonenumber());
        // 所属公司如果不是总公司,则要在该分公司下创建部门
        if (param.getDistributionUser().getParentBranchId() != 1) { //
            // 根据分公司id获取到userId
            ErpDistributionUser branchOfficeInfoVo = distributionUserService.getDistributionUserById(param.getDistributionUser().getParentBranchId());
            Long branchUserId = branchOfficeInfoVo.getUserId();
            R<Object> objectR1 = remoteUserService.selectUserById(branchUserId);
            SysUser branchUser = JSONObject.parseObject(JSONObject.toJSONString(objectR1.getData()), SysUser.class);
            sysDept.setParentId(branchUser.getDeptId());
        }else { // 部门加入到总公司下
            sysDept.setParentId(101L);
        }
        sysDept.setOrderNum(0);
        R<Object> insert = remoteDeptService.insert(sysDept, SecurityConstants.INNER);
        if (insert.getCode() != 200)
            return R.fail(insert.getMsg());
        Long deptId = remoteDeptService.searchByDeptName(param.getDistributionUserBasicInfo().getCorporateName());
        // 为新用户分配部门
        user.setDeptId(deptId);
        // 为新用户分配角色：代理
        user.setRoleIds(new Long[]{1656968210227023873L});
        user.setNickName(sysDept.getDeptName());
        // 注册系统用户
        remoteUserService.registerUser(user, SecurityConstants.INNER);
        R<LoginUser> userInfo = remoteUserService.getUserInfo(user.getUserName(), SecurityConstants.INNER);
        if (userInfo.getData() == null) {
            throw new RuntimeException("获取用户失败");
        }
        Long userId = userInfo.getData().getSysUser().getUserId();


        /** 注册分销用户 **/
        // 获取注册分销用户所需信息
        ErpDistributionUser distributionUser = param.getDistributionUser();


        ErpDistributionUser parentDistributionUser = null;
        if(distributionUser.getParentId() == null){
            if(distributionUser.getParentBranchId() == null){
                return R.fail("推荐人获取失败，请联系管理员");
            }
            // 分公司直推
            distributionUser.setParentId(distributionUser.getParentBranchId());

        }
        // 获取到上级的父类ids
        parentDistributionUser = distributionUserService.getDistributionUserById(distributionUser.getParentId());
        String parentIds = parentDistributionUser.getParentIds();
        if (parentIds.equals("0")) {
            // 说明是总公司推荐
            distributionUser.setParentIds("1");
        }else {
            // 分公司推荐的
            distributionUser.setParentIds(parentIds + "," + distributionUser.getParentId().toString());
            distributionUser.setParentBranchId(parentDistributionUser.getDistributionUserId());
            distributionUser.setBindTime(new Date());
            distributionUser.setParentBranchId(parentDistributionUser.getDistributionUserId());
        }

        distributionUser.setUserId(userId);
        // 生成身份代码
        distributionUser.setIdentityCode(distributionUserService.createIdentityCode(2));
        // 生成邀请码
        distributionUser.setInvitationCode(distributionUserService.createInvitationCode());
        // 分销员类型：代理
        distributionUser.setType(2);
        // 状态：正常
        distributionUser.setState(1);
        // 注册分销员
        Long distributionId = distributionUserService.insertDistributionUser(distributionUser);
        // 保存分销员基本信息
        ErpDistributionUserBasicInfo userBasicInfo = param.getDistributionUserBasicInfo();
        userBasicInfo.setDistributionUserId(distributionId);
        distributionUserBasicInfoMapper.insert(userBasicInfo);

        // 初始化钱包
        remoteWalletService.initWallet(distributionId, userId, SecurityConstants.INNER);


        /** 分销计算 **/
        Map<String, Object> divideMap = new HashMap<>();
        // 分销类型
        divideMap.put("distributionType", 2);
        // 是否分销 TODO 获取不到，暂时写死
//        divideMap.put("isDistribution", param.getIsDistribution());
        divideMap.put("isDistribution", 0);
        // 分销金额
        divideMap.put("distributionAmount", new BigDecimal(configService.getConfigKey("agent_amount").getMsg()));
        // 判断分销方式 TODO 自定义分销未做，默认固定方式
        divideMap.put("distributionMode",0);
        // 备注
        divideMap.put("remarks", "代理：" + distributionId + "-" + param.getDistributionUserBasicInfo().getCorporateName());

        // 代理独有的数据
        // 所属分公司
        if (distributionUser.getParentBranchId() != null){
            divideMap.put("parentBranchId",distributionUser.getParentBranchId());
        }

        // 分发计算
        rabbitTemplate.convertAndSend("distribution-event-exchange",
                "distribution.sale.system.divide", JSONObject.toJSONString(divideMap));

        return R.ok();
    }

    /**
     * 修改代理开户信息
     */
//  @SaCheckPermission("system:agentInfo:edit")
//    @Log(title = "代理开户信息", businessType = BusinessType.UPDATE)
//    @RepeatSubmit()
//    @PostMapping("/edit")
//    public R<Void> edit(@RequestBody DistributionParam param) throws Exception {
//
////        // 获取分公司的用户的手机号
////        List<String> phoneList = new ArrayList<>();
////        List<String> emailList = new ArrayList<>();
////        SysUser user = param.getUser();
////        ErpAgentInfoBo info = param.getInfo();
////        List<ErpAgentInfoVo> erpBranchOfficeInfos = agentInfoMapper.selectVoList(new LambdaQueryWrapper<ErpAgentInfo>()
////                .ne(ErpAgentInfo::getUserId,info.getUserId()));
////        for (ErpAgentInfoVo officeInfo : erpBranchOfficeInfos) {
////            Long userId = officeInfo.getUserId();
////            R<Object> objectR = userService.selectUserById(userId);
////            String s = JSONObject.toJSONString(objectR.getData());
////            SysUser sysUser = JSONObject.parseObject(s, SysUser.class);
////            phoneList.add(sysUser.getPhonenumber());
////            emailList.add(sysUser.getEmail());
////        }
////
////        String userName = user.getUserName();
////        user.setUserId(info.getUserId()); // 校验剔除该id
//////        userService.checkUserAllowed(user);
//////        userService.checkUserDataScope(user.getUserId());
//////        if (UserConstants.NOT_UNIQUE.equals(userService.checkUserNameUnique(user))) {
//////            return R.fail("修改用户'" + userName + "'失败，登录账号已存在");
//////        } else if (StringUtils.isNotEmpty(user.getPhonenumber())
//////                && phoneList.contains(user.getPhonenumber())) {
//////            return R.fail("修改用户'" + userName + "'失败，手机号码已存在");
//////        } else if (StringUtils.isNotEmpty(user.getEmail())
//////                && emailList.contains(user.getEmail())) {
//////            return R.fail("修改用户'" + userName + "'失败，邮箱账号已存在");
//////        }
////        R<Object> objectR = userService.selectUserById(info.getUserId());
////        String s = JSONObject.toJSONString(objectR.getData());
////        SysUser sysUser = JSONObject.parseObject(s, SysUser.class);
////        sysUser.setUserName(userName);
////        sysUser.setEmail(user.getEmail());
////        sysUser.setPhonenumber(user.getPhonenumber());
////        userService.updateUser(sysUser);
////        // 修改部门名称
////        Long deptId = sysUser.getDeptId();
////        R<SysDept> sysDeptR = deptService.getInfo(deptId);
////        SysDept sysDept = JSONObject.parseObject(JSON.toJSONString(sysDeptR), SysDept.class);
////        sysDept.setDeptName(info.getCorporateName());
////        deptService.edit(sysDept);
////
////        return toAjax(iErpAgentInfoService.updateByBo(info));
//        return R.ok();
//    }

    /**
     *TODO 删除代理开户信息
     *
     * @param ids 主键串
     */
    // @SaCheckPermission("system:agentInfo:remove")
//    @Log(title = "代理开户信息", businessType = BusinessType.DELETE)
//    @Transactional
//    @GetMapping("/delete")
//    public R<Void> remove(String ids) {
////        List<String> collect = Arrays.stream(ids.split(",")).collect(Collectors.toList());
////        for (String s : collect) {
////            Long id = Long.parseLong(s);
////            ErpAgentInfo info = agentInfoMapper.selectById(id);
////            Long userId = info.getUserId();
////            Long deptId = info.getDeptId();
//////            List<SysUser> sysUsers = userMapper.selectList(new LambdaQueryWrapper<SysUser>()
//////                    .eq(SysUser::getDeptId, deptId).ne(SysUser::getUserId,userId));
//////            if (sysUsers != null && sysUsers.size() != 0 ) {
//////                return R.fail("代理下存在用户,无法删除");
//////            }else {
////
//////                deptService.deleteDeptById(deptId);
////                userService.deleteUserById(userId);
////                agentInfoMapper.deleteById(info);
//////            }
////        }
//        return R.ok();
//    }

    /**
     * 代理历史数据推广提成数据重跑
     */
//    @GetMapping("/agentInfoRerun")
//    public R<String> agentInfoRerun() {
////        List<ErpAgentInfo> list=agentInfoMapper.selectList();
////        for (ErpAgentInfo info:list){
////            if(StringUtils.isEmpty(info.getParentId())&&StringUtils.isEmpty(info.getBranchId())){
////                continue;
////            }
////            // 获取到上级的父类ids
////            String parentId = info.getParentId();
////            String parentCode = null; // 推荐人的代码
////            if (StringUtils.isNotEmpty(parentId)) {
////                ErpAgentInfoVo agentInfoVo = iErpAgentInfoService.queryById(Long.parseLong(parentId));
////                String parentIds = agentInfoVo.getParentIds();
////                if (StringUtils.isNotEmpty(parentIds)) {
////                    parentIds = parentIds + "," +  parentId;
////                }else {
////                    parentIds = parentId;
////                }
////                info.setParentIds(parentIds);
////                parentCode = agentInfoVo.getCode();
////                // 获取上级所属部门
//////            Long agentUserId = agentInfoVo.getUserId();
//////            SysUser agentUser = userService.selectUserById(agentUserId);
//////            sonDept.setParentId(agentUser.getDeptId());
////            }
////            if (StringUtils.isEmpty(parentId)) {
////                if (StringUtils.isNotEmpty(info.getBranchId())) { // 所属分公司不为空,说明要在该分公司下创建部门
////                    // 根据分公司id获取到部门
////                    ErpBranchOfficeInfoVo branchOfficeInfoVo = branchOfficeInfoService.queryById(Long.valueOf(info.getBranchId()));
////                    parentCode = branchOfficeInfoVo.getCode();
////                }
////            }
////
////            R<Object> configKey = configService.getConfigKey("agent_amount");
////            String agentAmount = configKey.getMsg();
////            BigDecimal amount = new BigDecimal(agentAmount);
////            // 4. 访问分销接口
////            /**
////             * 分佣
////             * @param userId        被推广用户id
////             * @param userType      被推广用户类型（1分公司 2代理 3个人）
////             * @param recommendTime 推荐时间
////             * @param parentCode      推荐客户编码
////             * @param amount        金额
////             * @param isDivide      是否分佣 0否 1是
////             * @param orderNo       订单号
////             */
////            distributePropService.divide(info.getUserId(), 2, info.getCreateTime(), parentCode, amount, 0, "D"+(info.getId() + 999));
////        }
//
//        return R.ok();
//    }

}
